#include "FVec2RingBuffer.h"
#include "il_assert.h"

FVec2RingBuffer::FVec2RingBuffer() 
		: m_start( 0 ), m_count ( 0 ), m_max_size( 0 )
{
}

uint FVec2RingBuffer::GetMaxSize() const
{
	return m_max_size;
}

void FVec2RingBuffer::Create( int max_size )
{
	m_max_size = max_size;
	
	m_nodes = new CIwFVec2[max_size];
	m_count = 0;
	m_start = 0;
}

void FVec2RingBuffer::Destroy()
{
	delete[] m_nodes;
}

uint FVec2RingBuffer::GetCount() const
{
	return m_count;
}

void FVec2RingBuffer::Clear()
{
	m_count = 0;
}

void FVec2RingBuffer::Push( CIwFVec2 node )
{
	IL_ASSERT( m_max_size > 0, "the ring buffer was never created" );
	IL_ASSERT( (int) m_count < m_max_size, "reached the maximum number of nodes which can be added" );
	m_nodes[((m_start + m_count) %m_max_size)] = node;
	++m_count;
}

CIwFVec2 FVec2RingBuffer::Peek( uint offset ) const
{
	IL_ASSERT( m_max_size > 0, "the ring buffer was never created" );
	IL_ASSERT( offset < GetCount(), "tried to access an out of bound elements" );
	
	return m_nodes[((m_start + offset) % m_max_size)];
}

CIwFVec2 FVec2RingBuffer::Pop()
{
	IL_ASSERT( m_max_size > 0, "the ring buffer was never created" );
	IL_ASSERT( GetCount() > 0, "tried to pop from an empty ring" );
	
	CIwFVec2 element = Peek( 0 );
	
	++m_start;
	--m_count;
	
	return element;
}

void FVec2RingBuffer::TrimAfter( uint offset )
{
	IL_ASSERT( m_max_size > 0, "the ring buffer was never created" );
	IL_ASSERT( offset < GetCount(), "tried to trim after an offset which is outside the range of available nodes" );
	
	// to trim at the end we just have to reduce the count
	m_count = (m_count - ( m_count - (offset+1) ) );
}
